package com.base.netlib

import com.base.netlib.adapter.*
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.internal.bind.TypeAdapters
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.security.SecureRandom
import java.security.cert.CertificateException
import java.security.cert.X509Certificate
import javax.inject.Singleton
import javax.net.ssl.*


@Module
@InstallIn(SingletonComponent::class)
object NetModule {
    @Singleton
    @Provides
    fun provideOkHttp(): OkHttpClient {
        return NetLib.mOkHttpBuilder
            .sslSocketFactory(createSSLSocketFactory(), TrustAllCerts())
            .hostnameVerifier(TrustAllHostnameVerifier())
            .build()
    }

    private fun createSSLSocketFactory(): SSLSocketFactory {
        val sc = SSLContext.getInstance("TLS")
        sc.init(null, arrayOf<TrustManager>(TrustAllCerts()), SecureRandom())
        return sc.socketFactory
    }

    @Singleton
    @Provides
    fun provideRetrofit(gson: Gson, okHttpClient: OkHttpClient): Retrofit {
        return Retrofit.Builder()
            .baseUrl(NetLib.mBuilder.baseUrl)
            .addCallAdapterFactory(FlowCallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create(gson))
            .client(okHttpClient)
            .build()
    }

    @Singleton
    @Provides
    fun provideGson(): Gson {
        return GsonBuilder()
            .registerTypeAdapterFactory(
                TypeAdapters.newFactory(
                    Boolean::class.java,
                    Boolean::class.javaObjectType, BooleanConvertTypeAdapter()
                )
            )
            .registerTypeAdapterFactory(
                TypeAdapters.newFactory(
                    Float::class.java,
                    Float::class.javaObjectType, FloatConvertTypeAdapter()
                )
            )
            .registerTypeAdapterFactory(
                TypeAdapters.newFactory(
                    Double::class.java,
                    Double::class.javaObjectType, DoubleConvertTypeAdapter()
                )
            )
            .registerTypeAdapterFactory(
                TypeAdapters.newFactory(
                    Int::class.java,
                    Int::class.javaObjectType, IntConvertTypeAdapter()
                )
            )
            .create()
    }
}